import time
from datetime import timedelta

from uml.uml_manager import UmlManager
from uml.uml_transform import UmlTransform
from uml.uml_visitor import UmlVisitor
from gen.gen import Generator
from gen.gen_factory import JsonSerializableGenerator
from gen.gen_providers import QtPropProviderGenerator
from utils.file_util import FileUtil
from uml.uml_validate import UmlValidate


class main:
    xmi_info = {
        "dc": {
            "xmi": "uml/DC.xmi",
            "json": "uml-json/dc_orig.json",
            "json2": "uml-json/dc.json",
            "code": "dc",
        },
        "di": {
            "xmi": "uml/DI.xmi",
            "json": "uml-json/di_orig.json",
            "json2": "uml-json/di.json",
            "code": "di",
        },
        "uml": {
            "xmi": "uml/UML-v2.5-UML.xmi",
            "json": "uml-json/uml_orig.json",
            "json2": "uml-json/uml.json",
            "code": "uml",
        },
        "uml_pt": {
            "xmi": "uml/UML-v2.5-PrimitiveTypes.xmi",
            "json": "uml-json/uml_primitive_types_orig.json",
            "json2": "uml-json/uml_primitive_types.json",
        },
        "uml_profile": {
            "xmi": "uml/UML-v2.5-StandardProfile.xmi",
            "json": "uml-json/uml_standard_profile_orig.json",
            "json2": "uml-json/uml_standard_profile.json",
        },
        "uml_di": {
            "xmi": "uml/UML-v2.5-UMLDI.xmi",
            "json": "uml-json/uml_di_orig.json",
            "json2": "uml-json/uml_di.json",
            "code": "umldi",
        },
    }

    def __init__(self) -> None:
        self.m = UmlManager()

    def run(self):
        self.__to_json()

        self.__to_codes()

        # self.__visit()

    def gen_property_provider(self):
        self.__to_json()

        self.__gen_property_providers()

        # self.__visit()

    def __to_json(self):
        self.__get_model("dc", main.xmi_info["dc"]["xmi"], main.xmi_info["dc"]["json"])
        self.__get_model("di", main.xmi_info["di"]["xmi"], main.xmi_info["di"]["json"])
        self.__get_model(
            "uml", main.xmi_info["uml"]["xmi"], main.xmi_info["uml"]["json"]
        )
        self.__get_model(
            "uml_pt", main.xmi_info["uml_pt"]["xmi"], main.xmi_info["uml_pt"]["json"]
        )
        self.__get_model(
            "uml_profile",
            main.xmi_info["uml_profile"]["xmi"],
            main.xmi_info["uml_profile"]["json"],
        )
        self.__get_model(
            "uml_di", main.xmi_info["uml_di"]["xmi"], main.xmi_info["uml_di"]["json"]
        )

        self.__transform()

        # save tansformed model
        self.__model_to_json("dc", main.xmi_info["dc"]["json2"])
        self.__model_to_json("di", main.xmi_info["di"]["json2"])
        self.__model_to_json("uml", main.xmi_info["uml"]["json2"])
        self.__model_to_json("uml_pt", main.xmi_info["uml_pt"]["json2"])
        self.__model_to_json("uml_profile", main.xmi_info["uml_profile"]["json2"])
        self.__model_to_json("uml_di", main.xmi_info["uml_di"]["json2"])

    def __transform(self):
        t = UmlTransform()
        t.exec(self.m.model)

    def __visit(self):
        t = UmlVisitor()
        t.visit(self.m.model)

    def __to_codes(self):
        self.__to_code("dc", main.xmi_info["dc"]["code"])
        # self.__to_code("di", main.xmi_info["di"]["code"])
        self.__to_code("uml", main.xmi_info["uml"]["code"])
        self.__to_code("uml_di", main.xmi_info["uml_di"]["code"])
        self.__to_code_factory()

    def __to_code(self, key: str, path: str):
        # Gen code
        output_path = FileUtil.app_path("..", "uml-model-cpp", path)
        # FileUtil.rm_dir(output_path)
        gen = Generator(output_path)
        gen.gen_model(self.m.model, key)

    def __to_code_factory(self, path: str = "umlcore"):
        # Gen code
        output_path = FileUtil.app_path("..", "uml-model-cpp", path)
        gen = JsonSerializableGenerator(output_path)
        gen.gen_model(self.m.model)

    def __get_model(self, key: str, xmi: str, json: str):
        self.m.to_model(FileUtil.app_path("data", xmi), key)
        json_file = FileUtil.app_path("data", json)
        self.m.model_to_json(json_file, key)

    def __model_to_json(self, key: str, json: str):
        json_file = FileUtil.app_path("data", json)
        self.m.model_to_json(json_file, key)

    def __validate(self):
        # Validate
        v = UmlValidate()
        v.validate(self.m.model)

    def __gen_property_providers(self):
        gen = QtPropProviderGenerator(self.m.model, "./result/providers")
        gen.gen()


if __name__ == "__main__":
    start_time = time.time()

    app = main()
    # app.run()
    app.gen_property_provider()

    end_time = time.time()
    print(timedelta(seconds=end_time - start_time))
